$PBExportHeader$uo_ds_filtro.sru
forward
global type uo_ds_filtro from uo_ds
end type
end forward

global type uo_ds_filtro from uo_ds
end type
global uo_ds_filtro uo_ds_filtro

type variables
String	is_select
String	is_from
String	is_where
String	is_join
String	is_postwhere

end variables

forward prototypes
public function string uof_rearmar_sql (string as_sql_anterior)
public function integer uof_set_select (string as_select)
public function integer uof_set_from (string as_from)
public function integer uof_set_join (string as_join)
public function integer uof_set_where (string as_where[], string as_col_filtro[], string as_type_col_filtro[], string as_tabla[])
public function integer uof_reset_where ()
public function string uof_tabla_en_sql (string as_tabla, string as_col)
end prototypes

public function string uof_rearmar_sql (string as_sql_anterior);/*
	Funcion   	:		uof_rearmar_sql
	
	Descripcion	:		Dada la sintaxis del sql, rearmarlo con el contenido de las vbles de instancia is_select, 
							is_from, is_where, is_join
	
	Argumentos	:	   String as_sql_anterior ( sintaxis de SQL que se rearma )
	
	Retorna   	:		String ( nueva sintaxis )

*/

String	ls_nuevo_sql,	ls_sel,	ls_from,	ls_pre_orderby

ls_nuevo_sql = ""
ls_nuevo_sql = as_sql_anterior

//// Separar la parte del SELECT
//ls_sel = f_cortar_string(as_sql_anterior, "FROM"	)
//
//
//// Separar la parte del FROM
//ls_from = f_cortar_string(as_sql_anterior, "WHERE"	)
// Separar la parte del WHERE
//ls_where = f_cortar_string(as_sql_anterior, "ORDER BY")
//POR AHORA ESTO QUEDA COMENTADO, YA QUE SOLO SE AGREGAN CONDICIONES AL FINAL

IF is_where <> "" THEN
	
	// Separar (si existe) la parte del ORDER BY
	ls_pre_orderby = f_cortar_string(as_sql_anterior, "ORDER BY")
	//Agregar la condicion por filtros
	ls_nuevo_sql = ls_pre_orderby + " AND " + is_where 
	// Reinsertar la parte de ORDER BY
	IF as_sql_anterior <> "" THEN
		ls_nuevo_sql = ls_nuevo_sql + " ORDER BY " + as_sql_anterior
	END IF
	
END IF

// Separar (si existe) la parte del GROUP BY

RETURN ls_nuevo_sql




end function

public function integer uof_set_select (string as_select);/*
	Funcion   	:		uof_set_select
	
	Descripcion	:		Asigna el valor recibido en el argumento a la vble de instancia: is_select
	
	Argumentos	:	   String as_select ( conjunto de columnas a seleccionar )
	
	Retorna   	:		Integer

*/

is_select = as_select

RETURN 0
end function

public function integer uof_set_from (string as_from);/*
	Funcion   	:		uof_set_from
	
	Descripcion	:		Asigna el valor recibido en el argumento a la vble de instancia: is_from
	
	Argumentos	:	   String as_from ( conjunto de tablas de donde seleccionar )
	
	Retorna   	:		Integer

*/

is_from = as_from

RETURN 0
end function

public function integer uof_set_join (string as_join);/*
	Funcion   	:		uof_set_join
	
	Descripcion	:		Asigna el valor recibido en el argumento a la vble de instancia: is_join
	
	Argumentos	:	   String as_join ( conjunto de tablas del join )
	
	Retorna   	:		Integer

*/

is_join = as_join

RETURN 0
end function

public function integer uof_set_where (string as_where[], string as_col_filtro[], string as_type_col_filtro[], string as_tabla[]);/*
	Funcion   	:		uof_set_where
	
	Descripcion	:		Asigna el valor recibido en el argumento a la vble de instancia: is_where
	
	Argumentos	:	   String as_where ( conjunto de condiciones del sql - filtros )
	
	Retorna   	:		Integer

*/

Integer	li_i
String	ls_columna,	ls_tabla,	ls_col_filtro,	ls_valor, ls_where, ls_where_local,	ls_cond
Long		ll_c

IF UpperBound(aS_where) > 0 THEN

	// Iniciar la condicion que se genera en un llamado a la funcion
	ls_where_local = '( '
	
	FOR li_i = 1 TO UpperBound(as_where) 
		// Iniciar el string que va a tener un conjunto de condiciones para un conjunto de columnas
		ls_where = '('
		
		FOR ll_c = 1 TO UpperBound(as_col_filtro)
		
			// Obtener el nombre de la tabla que corresponde a esta columna
			IF (Pos(as_col_filtro[ll_c], '.') <= 0) THEN
				ls_col_filtro = as_col_filtro[ll_c]
			ELSE
				ls_col_filtro = Right(as_col_filtro[ll_c], Len(as_col_filtro[ll_c]) - Pos(as_col_filtro[ll_c], '.'))
			END IF

			// Buscar tabla del sql donde aparece la columna por primera vez
			ls_tabla = uof_tabla_en_sql(as_tabla[ll_c], ls_col_filtro)

			// Reconstruir la columna de filtro// Armar el nombre completo de tabla.columna
			IF ls_tabla <> '' THEN
				ls_columna = ls_tabla + '.' + ls_col_filtro
			ELSE
				RETURN -1
			END IF
						
			// Obtener instancia de valor, dentro de la posicion li_i del array, con separacion '~t'
			ls_valor = f_cortar_string(as_where[li_i], '~t')
			
			// Armar la condicion en ls_cond
			CHOOSE CASE Lower(Left(as_type_col_filtro[ll_c], 4))
				CASE 'stri', 'char', 'varc'
					IF (ls_valor = 'null') OR (ls_valor = '') THEN
						ls_cond = ls_columna + " IS NULL OR " + ls_columna + " = '" + ls_valor + "'"
					ELSE
						ls_cond = ls_columna + " = '" + ls_valor + "'"
					END IF
				CASE ELSE
					IF (ls_valor = 'null') THEN
						ls_cond = ls_columna + " IS " + ls_valor
					ELSE
						ls_cond = ls_columna + " = " + ls_valor
					END IF
			END CHOOSE
			
			// Agregar la condicion a ls_where
			IF Pos(ls_where,'(') = Len(ls_where) THEN 
				ls_where = ls_where + ls_cond
			ELSE
				ls_where = ls_where + ' AND ' + ls_cond
			END IF
					
		NEXT	// Hasta aca: ls_where para un conjunto completo
		
		// Cerrar ls_where con parentesis
		ls_where = ls_where + ')'
		
		// Agregar ls_where a ls_where_local
		IF Pos(ls_where_local, '( ') = Len(ls_where_local) - 1 THEN
			ls_where_local = ls_where_local + ls_where
		ELSE
			ls_where_local = ls_where_local + ' OR ' + ls_where
		END IF
		
	NEXT	// Hasta aca, ls_where_local completo
	
	// Cerrar parentesis en ls_where_local
	ls_where_local = ls_where_local + ' )'
	
	// Agregar ls_where_local a la vble de instancia is_where
	IF is_where = '' THEN
		is_where = ls_where_local
	ELSE	
		is_where = is_where + " AND " + ls_where_local
	END IF
	
END IF

RETURN 0
end function

public function integer uof_reset_where ();is_where = ''

RETURN 0
end function

public function string uof_tabla_en_sql (string as_tabla, string as_col);

String	ls_sintaxis,  ls_desc,	ls_from, ls_tabla,	ls_outer
Boolean	lb_existe
Integer	li_cant

as_tabla = Lower(as_tabla)

// Obtener la sintaxis del sql de la dw
ls_sintaxis = THIS.Describe("DataWindow.Table.Select")

// Descartar la parte del select 
ls_desc = f_cortar_string(ls_sintaxis, "FROM")

// Extraer la parte de from ( tablas )
ls_from = f_cortar_string(ls_sintaxis, "WHERE")

// Verificar si la tabla existe en el conjunto
lb_existe = FALSE

ls_from = Lower(ls_from)

ls_outer = ''

// Buscar la primera tabla donde existe la columna

DO WHILE (ls_from <> '') AND (NOT lb_existe)
	ls_tabla = Lower(Trim(f_cortar_string(ls_from,',')))
	
	//Eliminar los tabs y espacios 
	ls_tabla = trim( f_trim_nonprint(ls_tabla) )
	
	IF Pos(ls_tabla, 'outer') = 0 THEN
		
		IF Pos(ls_tabla, 'dba.') = 1 THEN
			// Extraer esa parte
			ls_tabla = Right(ls_tabla, Len(ls_tabla) - 4)
		END IF	
	
		SELECT COUNT(colno) 	INTO :li_cant
		FROM	 informix.syscolumns, informix.systables
		WHERE	 (colname = :as_col) 	
		AND    (tabname = :ls_tabla)
		AND	 (informix.syscolumns.tabid = informix.systables.tabid);
	
		IF (SQLCA.SQLCODE = 0) THEN
			lb_existe = (li_cant > 0)
		END IF
		
	ELSE
		// LA TABLA TIENE OUTER JOIN: Ignorarla ya que un outer implica que para esa columna de esa tabla puede no
		// haber valores
		//ls_tabla = Right(ls_tabla, Len(ls_tabla) - 6)
		ls_outer = Right(ls_tabla, Len(ls_tabla) - 6)
		
		IF Pos(ls_outer, 'dba.') = 1 THEN
			// Extraer esa parte
			ls_outer = Right(ls_outer, Len(ls_outer) - 4)
		END IF	
	
		SELECT COUNT(colno) 	INTO :li_cant
		FROM	 informix.syscolumns, informix.systables
		WHERE	 (colname = :as_col) 	
		AND    (tabname = :ls_outer)
		AND	 (informix.syscolumns.tabid = informix.systables.tabid);
	
		IF (SQLCA.SQLCODE = 0) THEN
			IF li_cant = 0 THEN
				ls_outer = ''
			ELSE
				// nada
			END IF
		END IF
		
		
	END IF
	
LOOP

IF NOT lb_existe THEN
	// retornar el outer
	RETURN ls_outer
ELSE
	RETURN ls_tabla
END IF
end function

on uo_ds_filtro.create
call super::create
end on

on uo_ds_filtro.destroy
call super::destroy
end on

event sqlpreview;/*
	Verificar tipo de SQL
	Si el tipo es : SELECT
	Rearmar el SQL, con los filtros recibidos desde la ventana que tiene pegada una instancia de este objeto
	Modificar el SQL
	Ejecutar el SQL

*/

String	ls_sintaxis

IF sqltype = PreviewSelect! THEN
	
	// Rearmar SQL
	ls_sintaxis = THIS.uof_rearmar_sql(sqlsyntax)
	
	// Modificar el SQL	
	THIS.SetSQLPreview(ls_sintaxis)
	
END IF

//Retorno 0: Continua ejecutando el SQL




end event

